#include "uart.h"
#include "kasm.h"

#define DLAB_ON 0x80	/* DLAB enabled */
#define DLAB_OFF 0x0
#define RI_ON 0x01		/* Read Interrupt Enables */
#define AUX_OUT2_ON 0x08
#define FIFO1 0x01 /* 0x00 */
#define DATA_READY_RESET 0x71

/* http://en.wikibooks.org/wiki/Serial_Programming:8250_UART_Programming */
void
setupUART (int addr, int baud, unsigned char cant_bits, unsigned char paridad, 
				unsigned char stop_bit)
{
	char c = *((char *)addr + LCR);
	/* seteo LCR DLAB encendido */
	myout (addr + LCR, DLAB_ON);
	
	/* seteo el baud rate LCR*/
	myout (addr, 115200 / baud);
	//myout (addr+1, 115200 / 9600);
	
	/* FCR */
	myout (addr + FCR, FIFO1);
	
	/* apago DLAB */
	//myout (addr + LCR, DLAB_OFF);
	c = cant_bits | paridad | stop_bit;
	/* seteo las opciones del usuario */
	myout (addr + LCR, cant_bits | paridad | stop_bit);
	
	/* FCR */
	//myout (addr + FCR, FIFO1);
	
	/* seteo la interrupcion por recepcion de datos */
	myout (addr + IER, RI_ON);
		
	myout (addr + MCR, AUX_OUT2_ON);
	/* FCR */
	myout (addr + FCR, FIFO1);
	/* LSR */
	//myout (addr + LSR, DATA_READY);
		
	return ;
}

void
writeToUART (int addr, unsigned char c)
{
    int r;
    
    /*  Empty Transmitter Holding Register */
    //while ((readFromUART (addr + LSR) & 0x20) == 0)
    //        putChar ('Z');
    
    /* no recibo interrupciones mientras escribo al UART */
    _Cli();
	myout (addr + THR, c);
    _Sti();
	return ;
}	
	
void writeStrToUART (int addr, const char * str)
{
	int i = 0;
	while (str[i] != '\0')
		writeToUART (addr, str[i++]);
	writeToUART (addr, str[i]);
	return ;
}

int
readFromUART (int addr)
{
	int ans;
	_Cli();
	myin (addr, &ans);
	_Sti();
	return ans;
}
